﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PortaCapena.OdooJsonRpcClient.Attributes;
using PortaCapena.OdooJsonRpcClient.Converters;
using PortaCapena.OdooJsonRpcClient.Models;
using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using static OdooRpcClient.OdooEnum;

namespace OdooRpcClient.Model.Account
{
    [OdooTableName("account.tax")]
    [JsonConverter(typeof(OdooModelConverter))]
    public class AccountTaxOdooModel : IOdooModel
    {

        /// <summary>
        /// TypeTaxUse
        /// Selection
        /// Determines where the tax is selectable. Note : 'None' means a tax can't be used by itself, however it can still be used in a group. 'adjustment' is used to perform tax adjustment.
        /// required
        /// <summary>
        [JsonProperty("type_tax_use")]
        [Description("TypeTaxUse")]
        public TaxTypeAccountTaxOdooEnum TypeTaxUse { get; set; }

        /// <summary>
        /// TaxScope
        /// Selection
        /// Restrict the use of taxes to a type of product.
        /// <summary>
        [JsonProperty("tax_scope")]
        [Description("TaxScope")]
        public TaxScopeAccountTaxOdooEnum? TaxScope { get; set; }

        /// <summary>
        /// Active
        /// Boolean
        /// Set active to false to hide the tax without removing it.
        /// <summary>
        [JsonProperty("active")]
        [Description("Active")]
        public bool? Active { get; set; }

        /// <summary>
        /// CompanyId
        /// Many2one
        /// required
        /// res.company
        /// <summary>
        [JsonProperty("company_id")]
        [Description("CompanyId")]
        public long CompanyId { get; set; }

        /// <summary>
        /// ChildrenTaxIds
        /// Many2many
        /// account.tax
        /// <summary>
        [JsonProperty("children_tax_ids")]
        [Description("ChildrenTaxIds")]
        public long[] ChildrenTaxIds { get; set; }

        /// <summary>
        /// Sequence
        /// Integer
        /// The sequence field is used to define order in which the tax lines are applied.
        /// required
        /// <summary>
        [JsonProperty("sequence")]
        [Description("Sequence")]
        public int Sequence { get; set; }

        /// <summary>
        /// Amount
        /// Float
        /// required
        /// <summary>
        [JsonProperty("amount")]
        [Description("Amount")]
        public double Amount { get; set; }

        /// <summary>
        /// PriceInclude
        /// Boolean
        /// Check this if the price you use on the product and invoices includes this tax.
        /// <summary>
        [JsonProperty("price_include")]
        [Description("PriceInclude")]
        public bool? PriceInclude { get; set; }

        /// <summary>
        /// IncludeBaseAmount
        /// Boolean
        /// If set, taxes which are computed after this one will be computed based on the price tax included.
        /// <summary>
        [JsonProperty("include_base_amount")]
        [Description("IncludeBaseAmount")]
        public bool? IncludeBaseAmount { get; set; }

        /// <summary>
        /// Analytic
        /// Boolean
        /// If set, the amount computed by this tax will be assigned to the same analytic account as the invoice line (if any)
        /// <summary>
        [JsonProperty("analytic")]
        [Description("Analytic")]
        public bool? Analytic { get; set; }

        /// <summary>
        /// TaxGroupId
        /// Many2one
        /// required
        /// account.tax.group
        /// <summary>
        [JsonProperty("tax_group_id")]
        [Description("TaxGroupId")]
        public long TaxGroupId { get; set; }

        /// <summary>
        /// HideTaxExigibility
        /// Boolean
        /// <summary>
        [JsonProperty("hide_tax_exigibility")]
        [Description("HideTaxExigibility")]
        public bool? HideTaxExigibility { get; set; }

        /// <summary>
        /// TaxExigibility
        /// Selection
        /// Based on Invoice: the tax is due as soon as the invoice is validated.
        /// Based on Payment: the tax is due as soon as the payment of the invoice is received.
        /// <summary>
        [JsonProperty("tax_exigibility")]
        [Description("TaxExigibility")]
        public TaxDueAccountTaxOdooEnum? TaxExigibility { get; set; }

        /// <summary>
        /// CashBasisTransitionAccountId
        /// Many2one
        /// Account used to transition the tax amount for cash basis taxes. It will contain the tax amount as long as the original invoice has not been reconciled ; at reconciliation, this amount cancelled on this account and put on the regular tax account.
        /// account.account
        /// <summary>
        [JsonProperty("cash_basis_transition_account_id")]
        [Description("CashBasisTransitionAccountId")]
        public long? CashBasisTransitionAccountId { get; set; }

        /// <summary>
        /// InvoiceRepartitionLineIds
        /// One2many
        /// Distribution when the tax is used on an invoice
        /// account.tax.repartition.line
        /// invoice_tax_id
        /// <summary>
        [JsonProperty("invoice_repartition_line_ids")]
        [Description("InvoiceRepartitionLineIds")]
        public long[] InvoiceRepartitionLineIds { get; set; }

        /// <summary>
        /// RefundRepartitionLineIds
        /// One2many
        /// Distribution when the tax is used on a refund
        /// account.tax.repartition.line
        /// refund_tax_id
        /// <summary>
        [JsonProperty("refund_repartition_line_ids")]
        [Description("RefundRepartitionLineIds")]
        public long[] RefundRepartitionLineIds { get; set; }

        /// <summary>
        /// TaxFiscalCountryId
        /// Many2one
        /// Technical field used to restrict the domain of account tags for tax repartition lines created for this tax.
        /// res.country
        /// <summary>
        [JsonProperty("tax_fiscal_country_id")]
        [Description("TaxFiscalCountryId")]
        public long? TaxFiscalCountryId { get; set; }

        /// <summary>
        /// CountryCode
        /// Char
        /// The ISO country code in two chars. 
        /// You can use this field for quick search.
        /// <summary>
        [JsonProperty("country_code")]
        [Description("CountryCode")]
        public string CountryCode { get; set; }

        /// <summary>
        /// Name
        /// Char
        /// required
        /// <summary>
        [JsonProperty("name")]
        [Description("Name")]
        public string Name { get; set; }

        /// <summary>
        /// Description
        /// Char
        /// <summary>
        [JsonProperty("description")]
        [Description("Description")]
        public string Description { get; set; }

        /// <summary>
        /// AmountType
        /// Selection
        /// 
        ///  - Group of Taxes: The tax is a set of sub taxes.
        ///  - Fixed: The tax amount stays the same whatever the price.
        ///  - Percentage of Price: The tax amount is a % of the price:
        ///     e.g 100 * (1 + 10%) = 110 (not price included)
        ///     e.g 110 / (1 + 10%) = 100 (price included)
        /// - Percentage of Price Tax Included: The tax amount is a division of the price:
        ///     e.g 180 / (1 - 10%) = 200 (not price included)
        ///     e.g 200 * (1 - 10%) = 180 (price included)
        /// required
        /// <summary>
        [JsonProperty("amount_type")]
        [Description("AmountType")]
        public TaxComputationAccountTaxOdooEnum AmountType { get; set; }

        /// <summary>
        /// PythonCompute
        /// Text
        /// Compute the amount of the tax by setting the variable 'result'.

        /// :param base_amount: float, actual amount on which the tax is applied
        /// :param price_unit: float
        /// :param quantity: float
        /// :param company: res.company recordset singleton
        /// :param product: product.product recordset singleton or None
        /// :param partner: res.partner recordset singleton or None
        /// <summary>
        [JsonProperty("python_compute")]
        [Description("PythonCompute")]
        public string PythonCompute { get; set; }

        /// <summary>
        /// PythonApplicable
        /// Text
        /// Determine if the tax will be applied by setting the variable 'result' to True or False.
        /// :param price_unit: float
        /// :param quantity: float
        /// :param company: res.company recordset singleton
        /// :param product: product.product recordset singleton or None
        /// :param partner: res.partner recordset singleton or None
        /// <summary>
        [JsonProperty("python_applicable")]
        [Description("PythonApplicable")]
        public string PythonApplicable { get; set; }

        /// <summary>
        /// Id
        /// Integer
        /// <summary>
        [JsonProperty("id")]
        [Description("Id")]
        public long Id { get; set; }

        /// <summary>
        /// DisplayName
        /// Char
        /// <summary>
        [JsonProperty("display_name")]
        [Description("DisplayName")]
        public string DisplayName { get; set; }

        /// <summary>
        /// CreateUid
        /// Many2one
        /// res.users
        /// <summary>
        [JsonProperty("create_uid")]
        [Description("CreateUid")]
        public long? CreateUid { get; set; }

        /// <summary>
        /// CreateDate
        /// Datetime
        /// <summary>
        [JsonProperty("create_date")]
        [Description("CreateDate")]
        public DateTime? CreateDate { get; set; }

        /// <summary>
        /// WriteUid
        /// Many2one
        /// res.users
        /// <summary>
        [JsonProperty("write_uid")]
        [Description("WriteUid")]
        public long? WriteUid { get; set; }

        /// <summary>
        /// WriteDate
        /// Datetime
        /// <summary>
        [JsonProperty("write_date")]
        [Description("WriteDate")]
        public DateTime? WriteDate { get; set; }

        /// <summary>
        /// LastUpdate
        /// Datetime
        /// <summary>
        [JsonProperty("__last_update")]
        [Description("LastUpdate")]
        public DateTime? LastUpdate { get; set; }
    }


    // Determines where the tax is selectable. Note : 'None' means a tax can't be used by itself, however it can still be used in a group. 'adjustment' is used to perform tax adjustment.
    [JsonConverter(typeof(StringEnumConverter))]
    public enum TaxTypeAccountTaxOdooEnum
    {
        [EnumMember(Value = "sale")]
        Sales = 1,

        [EnumMember(Value = "purchase")]
        Purchases = 2,

        [EnumMember(Value = "none")]
        None = 3,
    }


    // Restrict the use of taxes to a type of product.
    [JsonConverter(typeof(StringEnumConverter))]
    public enum TaxScopeAccountTaxOdooEnum
    {
        [EnumMember(Value = "service")]
        Services = 1,

        [EnumMember(Value = "consu")]
        Goods = 2,
    }


    // Based on Invoice: the tax is due as soon as the invoice is validated.
    // Based on Payment: the tax is due as soon as the payment of the invoice is received.
    [JsonConverter(typeof(StringEnumConverter))]
    public enum TaxDueAccountTaxOdooEnum
    {
        [EnumMember(Value = "on_invoice")]
        BasedOnInvoice = 1,

        [EnumMember(Value = "on_payment")]
        BasedOnPayment = 2,
    }


    // 
    //     - Group of Taxes: The tax is a set of sub taxes.
    //     - Fixed: The tax amount stays the same whatever the price.
    //     - Percentage of Price: The tax amount is a % of the price:
    //         e.g 100 * (1 + 10%) = 110 (not price included)
    //         e.g 110 / (1 + 10%) = 100 (price included)
    //     - Percentage of Price Tax Included: The tax amount is a division of the price:
    //         e.g 180 / (1 - 10%) = 200 (not price included)
    //         e.g 200 * (1 - 10%) = 180 (price included)
    //         
    [JsonConverter(typeof(StringEnumConverter))]
    public enum TaxComputationAccountTaxOdooEnum
    {
        [EnumMember(Value = "group")]
        GroupOfTaxes = 1,

        [EnumMember(Value = "fixed")]
        Fixed = 2,

        [EnumMember(Value = "percent")]
        PercentageOfPrice = 3,

        [EnumMember(Value = "division")]
        PercentageOfPriceTaxIncluded = 4,

        [EnumMember(Value = "code")]
        PythonCode = 5,
    }

}
